home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mint110s / intr.spp < prev    next >
Text File  |  1994-02-02  |  14KB  |  531 lines

  1. ; Copyright 1992 Eric R. Smith
  2. ; All rights reserved.
  3.  
  4. %include "magic.i"
  5. ;
  6. ; interrupt wrapping routines; these should just save registers and call
  7. ; the appropriate C handlers, unless speed is a major problem
  8. ;
  9.     TEXT
  10. ;
  11. ; first, utilities for setting processor status level
  12. ;
  13.     XDEF    _spl7,_spl
  14. _spl7:
  15.     move.w    sr,d0
  16.     ori.w    #$0700,sr
  17.     rts
  18. _spl:
  19.     move.w    4(sp),sr
  20.     rts
  21.  
  22.     XDEF    _mint_5ms
  23.     XDEF    _mint_timer
  24.     XDEF    _mint_vbl
  25.     XREF    _timeout    ; C time routine
  26.     XREF    _old_timer    ; old GEMDOS time vector
  27.     XREF    _old_vbl    ; old GEMDOS vbl vector
  28.     XREF    _old_5ms
  29.     XREF    _build_context
  30.     XREF    _restore_context
  31.     XREF    _proc_clock        ; controls process' allocation of CPU time
  32.     XREF    _curproc
  33.     XREF    _enter_kernel
  34.     XREF    _leave_kernel
  35.     XREF    _preempt
  36.     XREF    _in_kernel
  37.  
  38. ; AKP: this code is hit once every 5ms; it updates the time fields of curproc.
  39. _mint_5ms:
  40.     move.l    a0,-(sp)
  41.     move.l    _curproc,a0
  42.     tst.w    _in_kernel
  43.     bne.s    L_systime
  44.     lea    P_USRTIME(a0),a0    ; get offset to curproc->usrtime
  45.     addq.l    #5,(a0)            ; update the time
  46.     move.l    (sp)+,a0
  47.     move.l    _old_5ms+8,-(sp)    ; branch to old vector
  48.     rts
  49. L_systime:
  50.     lea    P_SYSTIME(a0),a0    ; get offset to curproc->systime
  51.     addq.l    #5,(a0)
  52.     move.l    (sp)+,a0
  53.     move.l    _old_5ms+8,-(sp)
  54.     rts
  55.  
  56. _mint_timer:
  57.     movem.l    d0-d2/a0-a2,-(sp)    ; save C registers
  58.     jsr    _timeout
  59.     movem.l    (sp)+,d0-d2/a0-a2
  60.     move.l    _old_timer+8,-(sp)    ; jump to GEMDOS time vector
  61.     rts
  62.  
  63.     XREF    _kintr
  64.     XREF    _keyrec
  65.  
  66. _mint_vbl:
  67. %ifndef ONLY030
  68.     tst.w    ($59e).w        ; test longframe (AKP)
  69.     beq.s    L_short1
  70. %endif
  71.     clr.w    -(sp)            ; yes, long frames: push a frame word
  72. L_short1:
  73.     pea    L_comeback        ; push fake PC
  74.     move.w    sr,-(sp)        ; push status register
  75.     move.l    _old_vbl+8,-(sp)    ; go service the interrupt
  76.     rts
  77.  
  78. L_comeback:
  79.     move.w    d0,-(sp)        ; `repeated' keys don't generate
  80.     move.w    _keyrec+8,d0        ; interrupts...  check buffer and
  81.     cmp.w    _keyrec+6,d0        ; set hi byte of kintr so that
  82.     sne    _kintr            ; select can wake up before you
  83.     move.w    (sp)+,d0        ; release the key, etc.
  84.     tst.w    _proc_clock        ; has time expired yet?
  85.     beq.s    L_expired        ; yes -- maybe go switch processes
  86. L_out:
  87.     rte                ; no -- just return
  88.  
  89. L_expired:
  90.     btst    #5,(sp)            ; user mode?
  91.     bne.s    L_out            ; no -- switching is not possible
  92.     tst.w    ($43e).w        ; test floppy disk lock variable
  93.     bne.s    L_out            ; if locked, can't switch
  94.     tst.w    _in_kernel        ; are we doing a kernel operation?
  95.     bne.s    L_out
  96. L_switch:
  97.     clr.w    -(sp)            ; no frame format needed
  98.     move.l    _curproc,-(sp)
  99.     addq.l    #P_CTXT0,(sp)            ; to get &curproc->ctxt[SYSCALL]
  100.     jsr    _build_context        ; build context
  101.     move.l    _curproc,a0
  102.     move.l    (a0),sp            ; use curproc->sysstack
  103.     move.w    #0,-(sp)        ; not a system call
  104.     jsr    _enter_kernel        ; enter kernel
  105.     addq.w    #2,sp
  106.     jsr    _preempt        ; yield processor
  107.     ori.w    #$700,sr        ; spl7()
  108.     jsr    _leave_kernel        ; restore vectors
  109.     move.l    _curproc,a0
  110.     pea    4(a0)
  111.     jsr    _restore_context    ; back to user
  112.  
  113. ;
  114. ; reset routine -- called on a warm boot. Note that TOS sends the
  115. ; address to which we should return in register a6. Also note that
  116. ; the stack pointer is in an unknown state, so we set up our own
  117. ;
  118.     XDEF    _reset
  119.     XREF    _init_tail        ; see main.c
  120.     XREF    _restr_intr
  121.  
  122. _reset:
  123.     move.w    #$2700,sr        ; avoid interruption here
  124.     move.l    sp,_init_tail        ; save A7
  125.     lea    _init_tail,sp        ; set up temporary stack
  126.     lea    256(sp),sp
  127.     movem.l    d0-d2/a0-a2,-(sp)    ; save C registers
  128.     jsr    _restr_intr        ; restore interrupts
  129.     movem.l    (sp)+,d0-d2/a0-a2    ; restore registers
  130.     move.l    _init_tail,sp
  131.     jmp    (a6)            ; reset again
  132.  
  133. ;
  134. ; routine for doing a reboot
  135. ;
  136.     XDEF    _reboot
  137. _reboot:
  138.     move.w    #$2700,sr        ; avoid interrupts
  139.     move.l    (0).w,sp        ; get sp after reboot
  140.     move.l    (4).w,a6        ; get new reboot address
  141.     jmp    _reset
  142.  
  143. ;
  144. ; routine for mouse packet handling
  145. ;
  146.     XDEF    _newmvec
  147.     XDEF    _newjvec
  148.     XREF    _mouse_handler
  149. ; Experimental three button mouse support (by jr@ms.maus.de,
  150. ; August 4, 1992
  151. ;
  152. ; Should work with the mice shipped with Atari's ASV or
  153. ; compatible ones (like Golden Image GI-6000). Might not work
  154. ; on ST/STE systems with older IKBD's or keyboards. The middle mouse
  155. ; button is wired to one of the joystick directions on joystick one.
  156. ;
  157. ; _newmvec is the same as before with two exceptions:
  158. ; 1. the first byte of the packet is saved for the joystick handler
  159. ; 2. the bit for the middle mouse button is ored in
  160. ;
  161. ; _newjvec hooks into the joystick vector and chains to the normal
  162. ; handler. The middle mouse button state is saved in a special
  163. ; register for _newmvec, and a 'fake' mouse packet is set up
  164. ; (by merging the last mouse packet header, or-ing in the
  165. ; middle button state and using 0/0 for the x/y increment).
  166. ;
  167. ; the faked_packet and third_button variables are declared at the
  168. ; end of this file
  169.  
  170. _newmvec:
  171.     move.l    a0,-(sp)
  172.     move.b    (a0),d0
  173.     move.b    d0,faked_packet
  174.     or.b    third_button,d0
  175.     move.b    d0,(a0)
  176.     jsr    _mouse_handler
  177.     move.l    (sp)+,a0
  178.     rts
  179. ;
  180. ; routine for joystick packet handling (used for three button mice)
  181. ;
  182.     XDEF    _newjvec
  183.     XREF    _oldjvec
  184.  
  185. _newjvec:
  186.     move.l    a0,-(sp)    ; save a0 on the stack
  187.     move.b    2(a0),d0    ; joystick direction
  188.     and.b    #1,d0        ; middle mouse button in lowest bit
  189.     add.b    d0,d0        ; times 4
  190.     add.b    d0,d0
  191.     move.b    d0,third_button    ; save it for use in newmvec
  192.  
  193.     lea    faked_packet,a0    ; 'our' faked mouse event
  194.     move.b    (a0),d0
  195.     and.b    #$3,d0        ; unmask our mouse button
  196.     or.b    #$F8,d0        ; or in correct header
  197.     or.b    third_button,d0    ; or in the current status
  198.     move.b    d0,(a0)        ; write it back
  199.  
  200.     move.l    a0,-(sp)    ; pass pointer to fake packet
  201.     jsr    _mouse_handler    ; to \dev\mouse handler
  202.     addq.l    #4,sp        ; pop parameter
  203.     move.l    (sp)+,a0    ; restore original a0 value
  204.     move.l    _oldjvec,-(sp)    ; jump to original joystick handler
  205.     rts
  206. ;
  207. ; new ikbd keyboard interrupt vector
  208. ; kintr is a global variable that should be non-zero if a keyboard
  209. ; event occured
  210. ;
  211.     XDEF    _new_ikbd
  212.     XREF    _old_ikbd
  213.     XREF    _kintr
  214.  
  215. _new_ikbd:
  216.     move.w    #1,_kintr
  217.     move.l    _old_ikbd+8,-(sp)
  218.     rts            ; jump to system interrupt routine
  219.  
  220. ;
  221. ; simple signal handlers
  222. ; global variables referenced:
  223. ; in_kernel: (main.c): flag to indicate that we're in the MiNT kernel
  224. ; sig_routine: (signal.c): pointer to which signal catching routine to
  225. ;          call (e.g. for SIGBUS, or whatever)
  226. ;
  227.     XDEF    _new_bus,_new_addr,_new_ill,_new_divzero,_new_priv,_new_linef
  228.     XDEF    _new_trace,_new_chk,_new_trapv,_new_fpcp,_new_mmu,_new_pmmuacc
  229.     XDEF    _new_uninit,_new_spurious,_new_format,_new_cpv
  230.     XREF    _in_kernel,_sig_routine
  231.     XREF    _sigbus,_sigaddr,_sigill,_sigfpe,_sigpriv,_sigtrap
  232.     XREF    _haltformat,_haltcpv
  233.     XREF    _sig_exc
  234.     XREF    _mcpu
  235.     
  236. ;
  237. ; New bus error handler for memory protection: get the ssp and
  238. ; put it in the proc structure before calling
  239. ; _sigbus.  When the bus error happens in the kernel we don't save
  240. ; any contexts.
  241. ; We don't want to mess up any registers here because we might bring the
  242. ; page in and RTE.
  243. ;
  244.  
  245. _new_bus:
  246. %ifndef ONLY030
  247.     move.w    #$8,_sig_exc
  248.     cmp.l    #30,_mcpu
  249.     bne.s    noMMU
  250. %endif
  251.     move.l    #_mmu_sigbus,_sig_routine
  252. %ifndef ONLY030
  253.     bra.s    Do_sig
  254. noMMU:
  255.     move.l    #_nommu_sigbus,_sig_routine
  256. %endif
  257. Do_sig:
  258.     move.l    a0,-(sp)        ; save a0
  259.     move.l    _curproc,a0
  260.     move.l    sp,P_EXCSSP(a0)
  261.     addq.l    #4,P_EXCSSP(a0)
  262.     move.l    6(sp),P_EXCPC(a0)
  263.     move.l    (sp)+,a0
  264.  
  265.     tst.w    _in_kernel        ; are we already in the kernel?
  266.     bne.s    Kernel            ; yes
  267.     move.w    _sig_exc,-(sp)
  268.     move.l    _curproc,-(sp)
  269.     addq.l    #4,(sp)            ; push offset of save area
  270.     jsr    _build_context
  271.     move.l    _curproc,a4
  272.     move.l    (a4),sp            ; put us in the system stack
  273.     move.w    #0,-(sp)        ; not a GEMDOS call
  274.     jsr    _enter_kernel        ; set up kernel vectors
  275.     addq.w    #2,sp
  276.     move.l    _sig_routine,a1        ; get signal handling routine
  277.     jsr    (a1)            ; go do it
  278.     ori.w    #$0700,sr        ; spl7()
  279.     jsr    _leave_kernel        ; leave kernel
  280.     addq.w    #4,a4            ; get context save area address
  281.     move.l    a4,-(sp)        ; push it
  282.     jsr    _restore_context    ; restore the context
  283. ;
  284. ; here's what we do if we already were in the kernel
  285. ;
  286. Kernel:
  287.     movem.l    d0-d2/a0-a2,-(sp)    ; save reggies
  288.     move.l    _sig_routine,a1        ; get handler
  289.     jsr    (a1)            ; go do it
  290.     movem.l    (sp)+,d0-d2/a0-a2
  291.     rte
  292.  
  293. ;
  294. ; _mmu_sigbus: a pre-handler for _sigbus.  Check the reason for the bus
  295. ; error and report if it was a real access fault.
  296. ;
  297. _mmu_sigbus:
  298.     move.l    a2,-(sp)
  299.     move.l    _curproc,a0
  300.     move.l    P_EXCSSP(a0),a1        ; a1 is now exception_ssp
  301.     move.w    $A(a1),d0        ; d0 is SSR
  302.     move.l    $10(a1),a1        ; a1 is the access address
  303.     move.l    a1,P_EXCADDR(a0)    ; save the access address
  304.  
  305.     ptestr    d0,(a1),#7,a2        ; a2 is the table address
  306.     move.l    a2,P_EXCTBL(a0)        ; save table address in curproc
  307.     pmove    mmusr,P_EXCMMUSR(a0)    ; save resulting mmusr in curproc
  308.     move.l    (sp)+,a2
  309.     jmp    _sigbus        ; chain to bus-error handler
  310. %ifndef ONLY030
  311. ;
  312. ; _nommu_sigbus: handler for bus errors on machines without MMU
  313.  
  314. _nommu_sigbus:
  315.     move.l    _curproc,a0
  316.     move.l    P_EXCSSP(a0),a1
  317.     lea    $10(a1),a1        ; point to access address
  318.     tst.w    ($59e).w        ; test longframe
  319.     beq.s    NOMMU1
  320.     addq.w    #8,a1            ; on 68000, address is 8 bytes further
  321. NOMMU1:
  322.     move.l    (a1),P_EXCADDR(a0)    ; save the access address
  323.     jmp    _sigbus
  324. %endif
  325.  
  326. _new_addr:
  327. %ifndef ONLY030
  328.     move.w    #$c,_sig_exc
  329. %endif
  330.     move.l    #_sigaddr,_sig_routine
  331.     bra    Do_sig
  332. _new_ill:
  333. %ifndef ONLY030
  334.     move.w    #$10,_sig_exc
  335. %endif
  336.     move.l    #_sigill,_sig_routine
  337.     bra    Do_sig
  338. _new_divzero:
  339. %ifndef ONLY030
  340.     move.w    #$14,_sig_exc
  341. %endif
  342.     move.l    #_sigfpe,_sig_routine
  343.     bra    Do_sig
  344. _new_linef:
  345. %ifndef ONLY030
  346.     move.w    #$2c,_sig_exc
  347. %endif
  348.     move.l    #_sigill,_sig_routine
  349.     bra    Do_sig
  350. _new_chk:
  351. %ifndef ONLY030
  352.     move.w    #$18,_sig_exc
  353. %endif
  354.     move.l    #_sigfpe,_sig_routine
  355.     bra    Do_sig
  356. _new_trapv:
  357. %ifndef ONLY030
  358.     move.w    #$1c,_sig_exc
  359. %endif
  360.     move.l    #_sigfpe,_sig_routine
  361.     bra    Do_sig
  362. _new_fpcp:
  363. ; don't set _sig_exc - only needed for 68000 vectors
  364.     move.l    #_sigfpe,_sig_routine
  365.     bra    Do_sig
  366. _new_mmu:
  367. ; don't set _sig_exc - only needed for 68000 vectors
  368.     move.l    #_sigill,_sig_routine
  369.     bra    Do_sig
  370. _new_pmmuacc:
  371. ; don't set _sig_exc - only needed for 68000 vectors
  372.     move.l    #_sigbus,_sig_routine
  373.     bra    Do_sig
  374. _new_uninit:
  375. %ifndef ONLY030
  376.     move.w    #$3c,_sig_exc
  377. %endif
  378.     move.l    #_sigbus,_sig_routine
  379.     bra    Do_sig
  380. _new_spurious:
  381. %ifndef ONLY030
  382.     move.w    #$60,_sig_exc
  383. %endif
  384.     move.l    #_sigbus,_sig_routine
  385.     bra    Do_sig
  386. _new_format:
  387.     move.l    #_haltformat,_sig_routine
  388.     bra    Do_sig
  389. _new_cpv:
  390.     move.l    #_haltcpv,_sig_routine
  391.     bra    Do_sig
  392.  
  393.     XREF    _old_priv        ; old privilege violation vector
  394. _new_priv:
  395. %ifndef ONLY030
  396.     move.w    #$20,_sig_exc
  397. %endif
  398.     move.l    #_sigpriv,_sig_routine
  399. %ifndef ONLY030
  400.     tst.w    ($59e).w        ; 68000s always get SIGPRIV
  401.     beq    Do_sig
  402. %endif
  403.     movem.l    d0/a0,-(a7)
  404.     move.l    10(a7),a0        ; fetch exception address
  405.     move.w    (a0),d0
  406.     and.w    #$ffc0,d0        ; partially decode move sr,...
  407.     cmp.w    #$40c0,d0        ; and test it
  408.     movem.l    (a7)+,d0/a0        ; preserves the flags
  409.     bne    Do_sig            ; doesn't look like sr,...
  410.     move.l    _old_priv+8,-(sp)    ; let our parent handle it
  411.     rts
  412.  
  413. ; XBRA vectors from main.c
  414.     XREF    _old_dos,_old_bios,_old_xbios
  415.     XREF    _old_divzero,_old_chk,_old_trapv
  416.  
  417. _new_trace:
  418.     btst    #5,(a7)            ; only check when called from supervisor mode
  419.     beq.s    S_1
  420.     cmp.l    #_old_dos+12,2(a7)    ; lets not trace the kernel !
  421.     beq.s    S_2
  422.     cmp.l    #_old_xbios+12,2(a7)
  423.     beq.s    S_2
  424.     cmp.l    #_old_bios+12,2(a7)
  425.     beq.s    S_2
  426.     cmp.l    #_old_divzero+12,2(a7)
  427.     beq.s    S_2
  428.     cmp.l    #_old_trapv+12,2(a7)
  429.     beq.s    S_2
  430.     cmp.l    #_old_chk+12,2(a7)
  431.     beq.s    S_2
  432. ; add any other non-traceable entities here...
  433.  
  434. S_1:    move.w    #$24,_sig_exc
  435.     move.l    #_sigtrap,_sig_routine
  436.     bra    Do_sig
  437.  
  438. S_2:    and.w    #$3fff,(a7)        ; clear both trace bits
  439.     rte                ; and re-start the handler
  440.  
  441. ;
  442. ; BIOS disk vectors for pseudo-disks like U: and X:; these are present
  443. ; just in case some program (foolishly) attempts to access these drives
  444. ; directly and gets horribly confused
  445. ;
  446.     XREF    _old_getbpb    ; old Getbpb vector
  447.     XREF    _old_mediach    ; old Mediach vector
  448.     XREF    _old_rwabs    ; old Rwabs vector
  449.     XREF    _aliasdrv    ; array of drive aliases
  450.     XDEF    _new_getbpb
  451.     XDEF    _new_mediach
  452.     XDEF    _new_rwabs
  453.  
  454. _new_getbpb:
  455.     move.w    4(sp),d0    ; check the drive
  456.     cmp.w    #$1f,d0        ; legal drive?
  457.     bhi.s    noalias0    ; no
  458.     move.w    d0,d1        ; get index
  459.     add.w    d0,d1        ; convert to index
  460.     lea    _aliasdrv,a0
  461.     move.w    0(a0,d1.w),d1    ; alias drive?
  462.     beq.s    noalias0
  463.     move.w    d1,d0
  464.     subq.w    #1,d0        ; adjust for aliasdrv base of '@'
  465.     cmp.w    #$1f,d0        ; is this a legal drive?
  466.     bhi.s    nobpb        ; no -- ignore it
  467. noalias0:
  468.     cmp.w    #$14,d0        ; drive U:?
  469.     beq.s    nobpb        ; yes, no BPB available
  470.     move.l    _old_getbpb+8,a0    ; not our drive
  471.     jmp    (a0)        ; call the old vector for it
  472. nobpb:
  473.     moveq.l    #0,d0        ; 0 means "no BPB read"
  474.     rts
  475.  
  476. _new_mediach:
  477.     move.w    4(sp),d0    ; check the drive
  478.     cmp.w    #$1f,d0        ; legal drive?
  479.     bhi.s    noalias1    ; no
  480.     move.w    d0,d1        ; get index
  481.     add.w    d0,d1        ; convert to index
  482.     lea    _aliasdrv,a0
  483.     move.w    0(a0,d1.w),d1    ; alias drive?
  484.     beq.s    noalias1
  485.     move.w    d1,d0
  486.     subq.w    #1,d0        ; adjust for aliasdrv base
  487.     cmp.w    #$1f,d0        ; legal drive?
  488.     bhi.s    nobpb        ; no -- ignore it
  489. noalias1:
  490.     cmp.w    #$14,d0        ; drive U:?
  491.     beq.s    nochng        ; yes, no change
  492.     move.l    _old_mediach+8,a0    ; not our drive
  493.     jmp    (a0)        ; call the old vector for it
  494. nochng:
  495.     moveq.l    #0,d0        ; 0 means "definitely no change"
  496.     rts
  497.  
  498. _new_rwabs:
  499.     move.w    $e(sp),d0    ; check the drive
  500.     cmp.w    #$1f,d0        ; legal drive?
  501.     bhi.s    noalias2    ; no
  502.     move.w    d0,d1        ; get index
  503.     add.w    d0,d1        ; convert to index
  504.     lea    _aliasdrv,a0
  505.     move.w    0(a0,d1.w),d1    ; alias drive?
  506.     beq.s    noalias2
  507.     move.w    d1,d0
  508.     subq.w    #1,d0        ; adjust for aliasdrv base
  509.     cmp.w    #$1f,d0        ; legal drive?
  510.     bhi.s    nobpb        ; no -- ignore it
  511. noalias2:
  512.     cmp.w    #$14,d0        ; drive U:?
  513.     beq.s    rwdone        ; yes, fake it
  514.     move.l    _old_rwabs+8,a0    ; not our drive
  515.     jmp    (a0)        ; call the old vector for it
  516. rwdone:
  517.     moveq.l    #0,d0        ; 0 means "successful operation"
  518.     rts
  519.  
  520.     DATA
  521. ; buffer for faked mouse packet (actually only 3 bytes)
  522.  
  523. faked_packet:
  524.     dc.l    0
  525.  
  526. ; here we store the additional button state
  527. third_button:
  528.     dc.w    0
  529.  
  530.     END
  531.